Data management tasks in object-oriented programming are typically implemented by manipulating objects, which are almost always non-scalar values. Consider the example of an address book entry, which represents a single person along with zero or more phone numbers and zero or more addresses. This could be modeled in an object-oriented implementation by a “person object” with “slots” to hold the data that comprise the entry, e.g., the person's name, a list (or array) of phone numbers, and a list of addresses. The list of phone numbers would itself contain “phone number objects” and so on. The address book entry may be treated as a single value by the programming language (it can be referenced by a single variable, for instance). Various methods can be associated with the object, such as a method to return the preferred phone number, the home address, and so on.
Many popular database products, however, such as SQL DBMS products, can only store and manipulate scalar values such as integers and strings, organized within tables. The developer must either convert the object values into groups of simpler values for storage in the database (and convert them back upon retrieval), or only use simple scalar values within the program. Object-relational mapping is used to implement the first approach. A challenge with object-relational mapping is translating those objects to forms which can be stored in the database, and which can later be retrieved easily, while preserving the properties of the objects and their relationships; these objects are then said to be persistent.
In programming, persistence refers specifically to the ability to retain data structures between program executions, such as, for example, an image editing program saving complex selections or a word processor saving undo history. This is generally achieved in practice by storing the data in non-volatile storage such as a file system, a database, or an object database.
A common type of database used is the relational database. Relational databases use a series of tables to organize data. Data in different tables are associated through the use of declarative constraints, rather than explicit pointers or links. The same data that can be stored in a single object value would likely need to be stored across several of these tables.
An object-relational mapping implementation would need to systematically and predictably choose which tables to use and generate the necessary SQL. Many software applications have been developed to reduce the tedium of developing object-relational mapping systems by providing libraries of classes which are able to perform mappings automatically. Given a list of tables in the database, and objects in the program, they will automatically map requests from one to the other. Asking a “person object” for its “phone numbers” will result in the proper query being created and sent, and the results being translated directly into “phone number objects” inside the program.
Additionally, many middleware projects in the object relation and object database areas have included techniques referred to as bijection. Bijection refers to copying data from a database or store and inserting that data into objects or graphs of objects. The bijector bridges between application provided objects and a relational database defined by a schema. The schema describes the database in terms of entities with keys and attributes as well as relationships between the entities such as one to many, many to one, one to one, etc. The application objects are also annotated with metadata indicating how the database should be projected to these objects (e.g., entity A goes to object B, attribute X of entity B goes to object B's name attribute, etc.). Relationships are similarly mapped. The bijection engine (middleware) can then be called by the application and provided with the relational database to copy data between the application's objects and the database. The application then can examine and/or modify these objects while the middleware determines what has changed and applies the changes to the relational database. J2EE servers, for example, include a Container-Managed Persistence (“CMP”) engine that copies/inserts the data between Entity Beans and databases. These CMP engines, as well as other middleware applications, generally only work with relational databases or an application specific backend data store. If application developers want to use a bijection engine for any other purpose then they need to write their own.
What is needed therefore is a bijection engine that is able to work with any abstract data store with a schema, that doesn't require additional programming on the part of application developers.